#pragma once

enum MouseButton { MOUSE_NONE, MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE, MOUSE_4, MOUSE_5, MOUSE_MAX };

class MouseData
{
	/// <Summary> The key </Summary>
	unsigned short key;

	/// <Summary> The windows message </Summary>
	unsigned short buttonFlag;

	/// <Summary> The previous window message </Summary>
	unsigned short prevButtonFlag;

public:

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Default constructor </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	MouseData() : key(0), buttonFlag(0), prevButtonFlag(0) { }

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Constructor </Summary>
	///
	/// <Param name="_key">	The key. </Param>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	MouseData(MouseButton _key)
		: key(_key)
	{
		switch(key)
		{
		case MOUSE_LEFT:
			buttonFlag = RI_MOUSE_BUTTON_1_UP;
			break;
		case MOUSE_RIGHT:
			buttonFlag = RI_MOUSE_BUTTON_2_UP;
			break;
		case MOUSE_MIDDLE:
			buttonFlag = RI_MOUSE_BUTTON_3_UP;
			break;
		case MOUSE_4:
			buttonFlag = RI_MOUSE_BUTTON_4_UP;
			break;
		case MOUSE_5:
			buttonFlag = RI_MOUSE_BUTTON_5_UP;
			break;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Constructor </Summary>
	///
	/// <Param name="_buttonFlag">	The button flag </Param>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	MouseData(unsigned short _buttonFlag)
		: buttonFlag(_buttonFlag), prevButtonFlag(0)
	{
		key = GetKeyType(buttonFlag);
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Constructor </Summary>
	///
	/// <Param name="rawMouse"> 	The raw mouse data </Param>
	/// <Param name="prevMouse">	The previous mouse data </Param>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	MouseData(const RAWMOUSE &rawMouse, const MouseData& prevMouse)
	{
		buttonFlag = rawMouse.usButtonFlags;
		prevButtonFlag = prevMouse.buttonFlag;

		key = GetKeyType(buttonFlag);
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Resets the message </Summary>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	void ResetFlag()
	{
		prevButtonFlag = buttonFlag;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Less-than comparison operator. </Summary>
	///
	/// <Param name="right">	The mouse data on the right side </Param>
	///
	/// <Return>	True if the first parameter is less than the second </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	bool operator<(const MouseData &right) const
	{
		return buttonFlag < right.buttonFlag;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Greater-than comparison operator </Summary>
	///
	/// <Param name="right">	The mouse data on the right side </Param>
	///
	/// <Return>	True if the first parameter is greater than to the second </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	bool operator>(const MouseData &right) const
	{
		return buttonFlag > right.buttonFlag;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Equality operator </Summary>
	///
	/// <Param name="right">	The mouse data on the right side </Param>
	///
	/// <Return>	True if the parameters are considered equivalent </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	bool operator==(const MouseData &right) const
	{
		return buttonFlag == right.buttonFlag;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Non-Equality operator </Summary>
	///
	/// <Param name="right">	The mouse data on the right side </Param>
	///
	/// <Return>	True if the parameters are not considered equivalent. </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	bool operator!=(const MouseData &right) const
	{
		return buttonFlag == right.buttonFlag;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Query if this object has a key down message </Summary>
	///
	/// <Return>	true if the message is down, false if not </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	bool IsKeyDownEvent() const
	{
		return RI_MOUSE_LEFT_BUTTON_DOWN == buttonFlag ||
			RI_MOUSE_MIDDLE_BUTTON_DOWN == buttonFlag ||
			RI_MOUSE_RIGHT_BUTTON_DOWN == buttonFlag;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Query if this object is key up message </Summary>
	///
	/// <Return>	true if the message is up, false if not. </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	bool IsKeyUpEvent() const
	{
		return RI_MOUSE_LEFT_BUTTON_UP == buttonFlag ||
			RI_MOUSE_MIDDLE_BUTTON_UP == buttonFlag ||
			RI_MOUSE_RIGHT_BUTTON_UP == buttonFlag;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Gets the key </Summary>
	///
	/// <Return>	The key </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	unsigned short GetKey() const { return key; }

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Gets the button flag </Summary>
	///
	/// <Return>	The button flag </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	unsigned short GetButtonFlag() const { return buttonFlag; }

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Gets the previous button flag </Summary>
	///
	/// <Return>	The previous button flag </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	unsigned short GetPrevButtonFlag() const { return prevButtonFlag; }

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <Summary>	Gets a key type </Summary>
	///
	/// <Param name="type">	The type </Param>
	///
	/// <Return>	The key type </Return>
	////////////////////////////////////////////////////////////////////////////////////////////////////
	static unsigned short GetKeyType(unsigned short type)
	{
		if	   (type == RI_MOUSE_BUTTON_1_DOWN || type == RI_MOUSE_BUTTON_1_UP)
			return MOUSE_LEFT;
		else if(type == RI_MOUSE_BUTTON_2_DOWN || type == RI_MOUSE_BUTTON_2_UP)
			return MOUSE_RIGHT;
		else if(type == RI_MOUSE_BUTTON_3_DOWN || type == RI_MOUSE_BUTTON_3_UP)
			return MOUSE_MIDDLE;
		else if(type == RI_MOUSE_BUTTON_4_DOWN || type == RI_MOUSE_BUTTON_4_UP)
			return MOUSE_4;
		else if(type == RI_MOUSE_BUTTON_5_DOWN || type == RI_MOUSE_BUTTON_5_UP)
			return MOUSE_5;
		else
			return MOUSE_NONE;
	}
};